package com.lagou.edu.application;

import com.alibaba.druid.sql.visitor.functions.If;
import com.lagou.edu.annotations.T;
import com.lagou.edu.core.SummerBeanFactory;
import com.lagou.edu.factory.TransactionProxyFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 */
public class AnnotationBeanApplication implements SummerBeanFactory {

    private static Map<String,Object> beansMap = new HashMap<>();

    @Override
    public void registerBeanDefinition(String beanDefinition) throws ClassNotFoundException {
        try {
            beansMap.put(beanDefinition,Class.forName(beanDefinition).newInstance());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void registerBeanDefinition(Class beanDefinitionClass) throws ClassNotFoundException {
        try {
            beansMap.put(beanDefinitionClass.getName(),beanDefinitionClass.newInstance());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void destroyBeanDefinition(String beanDefinition) throws ClassNotFoundException {
        beansMap.remove(beanDefinition);
    }

    @Override
    public void destroyBeanDefinition(Class beanDefinitionClass) throws ClassNotFoundException {
        beansMap.remove(beanDefinitionClass.getName());
    }

    @Override
    public Map<String, Object> getBeansWithAnnotation(Class clazz) {
        return beansMap.entrySet().stream().filter(e->{
            return e.getValue().getClass().isAnnotationPresent(clazz);
        }).collect(Collectors.toMap(
                (e) -> (String) e.getKey(),
                (e) -> e.getValue()));
    }

    @Override
    public Map<String, Object> getBeans() {
        return beansMap;
    }

    @Override
    public void replaceBean(String beanDefinition, Object object) {
        beansMap.put(beanDefinition,object);
    }

    public <T> T getBean(Class<T> clazz) throws Exception{
        Object result = (T) beansMap.entrySet().stream().filter(e->{
            return clazz.isAssignableFrom(e.getValue().getClass());
        }).collect(Collectors.toList()).get(0).getValue();
        result =  ((TransactionProxyFactory)beansMap.get(TransactionProxyFactory.class.getName())).getJdkProxy(result);
        return (T) result;

    }
}
